package Q17_18_Shortest_Supersequence;
public class QuestionB {
/* Do backwards sweep to get a list of the next occurrence of value from each index. */
public static int[] getNextElement(int[] bigArray, int value) {
int next = -1;
int[] nexts = new int[bigArray.length];
for (int i = bigArray.length - 1; i >= 0; i--) {
if (bigArray[i] == value) {
next = i;
}
nexts[i] = next;
}
return nexts;
}
/* Create table of next occurrences. */
public static int[][] getNextElementsMulti(int[] big, int[] small) {
int[][] nextElements = new int[small.length][big.length];
for (int i = 0; i < small.length; i++) {
nextElements[i] = getNextElement(big, small[i]);
}
return nextElements;
}
/* Given an index and the table of next elements, find the closure
* for this index (which will be the min of this column. */
public static int getClosureForIndex(int[][] nextElements, int index) {
int max = -1;
for (int i = 0; i < nextElements.length; i++) {
if (nextElements[i][index] == -1) {
return -1;
}
max = Math.max(max, nextElements[i][index]);
}
return max;
}
/* Get closure for each index. */
public static int[] getClosures(int[][] nextElements) {
int[] maxNextElement = new int[nextElements[0].length];
for (int i = 0; i < nextElements[0].length; i++) {
maxNextElement[i] = getClosureForIndex(nextElements, i);
}
return maxNextElement;
}
/* Get shortest closure. */
public static Range getShortestClosure(int[] closures) {
int bestStart = -1;
int bestEnd = -1;
for (int i = 0; i < closures.length; i++) {
if (closures[i] == -1) {
break;
}
int current = closures[i] - i;
if (bestStart == -1 || current < bestEnd - bestStart) {
bestStart = i;
bestEnd = closures[i];
}
}
return new Range(bestStart, bestEnd);
}
public static Range shortestSupersequence(int[] big, int[] small) {
int[][] nextElements = getNextElementsMulti(big, small);
int[] closures = getClosures(nextElements);
return getShortestClosure(closures);
}
public static void main(String[] args) {
int[] array = {9, 5, 1, 0, 2, 1, 3, 5, 7, 9, 1, 1, 5, 8, 9, 7};
int[] set = {1, 5, 9};
System.out.println(array.length);
Range shortest = shortestSupersequence(array, set);
System.out.println(shortest.getStart() + ", " + shortest.getEnd());
}
}